import 'dart:convert';

import 'package:love_newf/app/com/base/L.dart';
import 'package:love_newf/app/com/model/request_default_params_model.dart';
import 'package:love_newf/app/com/view/common_view.dart';
import 'package:dio/dio.dart';
import 'dart:collection';

import 'package:flutter_easyloading/flutter_easyloading.dart';

import 'package:liuxlcommon/util/print_utils.dart';
import 'package:liuxlcommon/util/string_utils.dart';
import 'package:liuxlcommon/util/toast_util.dart';
import 'package:love_newf/app/com/base/app.dart';
import 'package:love_newf/app/com/http/code.dart';
import 'package:love_newf/app/com/http/Res.dart';
import 'package:love_newf/app/com/base/key_mix.dart';
import 'package:love_newf/generated/json/base/json_convert_content.dart';

//动态域名：https://mx02-dc.oss-us-west-1.aliyuncs.com/molo.json
//默认接口: https://molo.aaradhya-capital.com/facil/
//官网：https://aaradhya-capital.com/
//隐私协议：https://aaradhya-capital.com/MoloPrivacyPolicy.html     @小岩岩

class HttpRequest {
  static String TAG = "HttpRequest";
  static String host = "";
  static String _baseUrl = "$host";
  static RequestDefaultParamsModel? requestDefaultParamsModel;
  static bool isProxy = false;

  static BaseOptions _options = getDefOptions();

  static Map optionParams = {"timeoutMs": 60000};

  static setBaseUrl(String baseUrl) {
    _baseUrl = baseUrl;
  }

  static String getBaseUrl() {
    return _baseUrl;
  }

  static BaseOptions getDefOptions() {
    BaseOptions options = BaseOptions();
    options.connectTimeout = const Duration(milliseconds: 100 * 1000);
    options.receiveTimeout = const Duration(milliseconds: 200 * 1000);
    // options.contentType = ContentType.parse('application/x-www-form-urlencoded');
    options.baseUrl = _baseUrl;
    Map<String, dynamic> headers = {};
    // headers['Accept'] = 'application/x-www-form-urlencoded';
    // headers['content-type'] = 'application/x-www-form-urlencoded';
    options.headers = headers;
    return options;
  }

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  get<T>(url, param,
      {context,
      loadingText,
      parse = true,
      Options? options,
      isnull,
      autoToast}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "GET"),
        isnull: isnull,
        autoToast: autoToast);
  }

  getList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "GET"),
        isList: true,
        isnull: isnull);
  }

  putList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isList: true,
        isnull: isnull);
  }

  putRes(url, param,
      {context, loadingText, parse = false, Options? options, isnull}) async {
    return await post(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isnull: isnull);
  }

  put<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isnull: isnull);
  }

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  Future postList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        isList: true,
        options: Options(method: "POST"),
        isnull: isnull);
  }

  Future postRes<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull, isList}) {
    return post(url, param,
        context: context,
        parse: false,
        options: options,
        isnull: isnull,
        isList: isList,
        loadingText: loadingText);
  }

  ///可以关闭
  static bool isDis = true;

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  Future post<T>(url, param,
      {context,
      loadingText,
      parse = true,
      Options? options,
      isnull,
      isList,
      isPrintLog = true,
      autoToast = true}) async {
    if (isnull == true) {
      var p = {};
      (param as Map).forEach((key, value) {
        if (value != null) p[key] = value;
      });
      param = p;
    }

    if (loadingText != null) {
      if (EasyLoading.isShow) {
        isDis = false;
      } else {
        EasyLoading.show(status: loadingText);
      }
    }
    String json = JsonEncoder().convert(param);

    if (isPrintLog) {
      PrintUtils.print1(TAG + 'token', App.token);
      PrintUtils.print1(TAG + 'url', url);
      PrintUtils.print1(TAG + 'param', json);
    }

    Res a = await request(url, param, {"token": App.token ?? ""},
        options ?? Options(method: "POST"),
        isPrintLog: isPrintLog);
    if (loadingText != null) {
      isDis = true;
      Future.delayed(const Duration(milliseconds: 30)).then((value) {
        if (isDis) {
          EasyLoading.dismiss();
        }
      });
    }
    if (!a.isSuccess() && autoToast == true) {
      ToastUtils.showToast(msg: a.msg);
    }
    if (parse) {
      if (a.data == null) return null;
      if (!a.success) return null;
      if (null is T) return a.data;
      if (isList ?? false) {
        if (a.data != null && a.data is List) {
          return JsonConvert().convertListNotNull<T>(a.data);
        } else if (a.data != null && a.data['list'] != null) {
          return JsonConvert().convertListNotNull<T>(a.data['list']);
        } else
          return <T>[];
      }
      return JsonConvert.fromJsonAsT<T>(a.data) ?? a.data;
    }
    return a;
  }

  postfile(path, Map<String, dynamic>? map,
      {context, loadingText, parse = true, Options? options}) async {
    map ??= <String, dynamic>{};
    String name = path.substring(path.lastIndexOf('/') + 1);
    PrintUtils.print1("postfile", json.encode(map));
    map["apartment"] = await MultipartFile.fromFile(path, filename: name);
    FormData formData = FormData.fromMap(map);
    if (loadingText != null) EasyLoading.show(status: loadingText);
    Res a = await request('/credit-info/upload-image'.hx, formData,
        {"token": App.token ?? ""}, options ?? Options(method: "POST"));
    if (loadingText != null) EasyLoading.dismiss();
    if (parse) {
      if (a.data == null) ToastUtils.showToast(msg: a.msg);
      return a.data;
    }
    return a;
  }

  static delete(url, param) async {
    return await request(url, param, null, Options(method: 'DELETE'));
  }

  ///发起网络请求
  ///[ url] 请求url
  ///[ params] 请求参数
  ///[ header] 外加头
  ///[ option] 配置
  static request(
      String url, params, Map<String, String>? header, Options option,
      {noTip = false, isPrintLog = true}) async {
    String lUrl = url;
    if (!url.contains("http")) {
      // if (isProxy) {
      //   _baseUrl = "http://149.129.247.212:8967/kredit";
      // } else {
      //   _baseUrl = "$host/kredit";
      // }
      url = _baseUrl + url;
    }
    if (StringUtils.isEmpty(requestDefaultParamsModel?.adid)) {
      // requestDefaultParamsModel =
      //     await DeviceDataPlugin.getRequestDefaultParams;
      requestDefaultParamsModel = RequestDefaultParamsModel();
      requestDefaultParamsModel?.appVersion =  "1.0.1";
      requestDefaultParamsModel?.deviceName =  "Iphone";
      requestDefaultParamsModel?.adid =  "adid";
      requestDefaultParamsModel?.deviceId =  "adfadfa";
      requestDefaultParamsModel?.deviceOsVersion =  "11.2/8.0.0";
    }
    Map<String, String> headers = HashMap();
    if (header != null) {
      headers.addAll(header);
    }
    headers.addAll({
      "saToken": L.loginUserInfo?.saToken ?? "",
      "deviceMac": requestDefaultParamsModel!.deviceId,
      "clientVersion": requestDefaultParamsModel!.appVersion
    });
    // 设置 baseUrl

    option.headers = headers;

    ///超时
    Dio dio = Dio(_options);
    if (!await checkInternetConnection()) {}

    ///启用代理不抓包
    // if (isProxy) {
    //   HttpProxy httpProxy = await HttpProxy.createHttpProxy();
    //   HttpOverrides.global = httpProxy;
    // }

    Response response;
    try {
      PrintUtils.print1(TAG + 'url', url);
      if (isPrintLog) {
        PrintUtils.print1(TAG + 'token', App.token);
        PrintUtils.print1(TAG + 'param', params);
        PrintUtils.print1(TAG + 'header', dio.options.headers);
      }

      if (option.method!.contains("GET")) {
        response = await dio.request(
          url,
          queryParameters: params,
          options: option,
        );
      } else {
        // var data = (params is FormData) ? params : FormData.fromMap(params);
        var data = params;
        response = await dio.request(
          url,
          data: data,
          options: option,
        );
      }
    } on DioError catch (e) {
      // 请求错误处理
      Response errorResponse;
      if (e.response != null) {
        errorResponse = e.response ??
            Response(statusCode: 666, requestOptions: RequestOptions(path: ""));
      } else {
        errorResponse = Response(
            statusCode: 666,
            statusMessage: e.message ?? "Network Error",
            requestOptions: RequestOptions(path: ""));
      }
      // if (e.type == DioErrorType.connectTimeout) {
      //   errorResponse.statusCode = Code.NETWORK_TIMEOUT;
      // }
      errorResponse.statusMessage ??= "";
      PrintUtils.print1('$TAG 请求异常 ',
          "code:${errorResponse.statusCode!}  message：${errorResponse.statusMessage!}");
      PrintUtils.print1('$TAG 请求异常 url ', url);
      if (errorResponse.data != null) {
        PrintUtils.print1(TAG + ' 请求异常 data ', errorResponse.data.toString());
      }

      if (errorResponse.data != null && errorResponse.data.length != 0) {
        if (errorResponse.data is String) {
          return Res(errorResponse.statusCode!, errorResponse.data, null);
        }
        return Res(
            errorResponse.statusCode!, errorResponse.data!.toString(), null);
      } else {
        return Res(
            errorResponse.statusCode!, errorResponse.statusMessage!, null);
      }
    }

    try {
      if (response.statusCode == 200 || response.statusCode == 201) {
        try {
          String json1 = json.encode(response.data);

          PrintUtils.print1('${lUrl.rhx}: data', json1);
        } catch (e) {
          PrintUtils.print1('${lUrl.rhx}: data', response.data.toString());
        }

        dynamic s = response.data;
        // s = StringKeyMix.jsonConvertMapHx(s);
        var a = Res(s["code"], s["message"] ?? "", s["data"]);

        // int code = int.parse(StringUtils.defaultValue(
        //     s['code'.hx].toString(), s['code'].toString()));
        // Res a = Res(   code, s['message']  ,   s['data']);
        if (!a.success) {
          print("sdf");
        }
        if (a.data is String && a.data.toString().contains('\r\n')) {
          dynamic s = json.decode(a.data.toString().replaceAll('\r\n', '\n'));
          a.data = s;
        }
        if (a.code == 401) {
          App.logout();
        }
        return a;
      }
    } catch (e) {
      return Res(
          Code.NETWORK_ERROR, response.statusCode.toString(), response.data);
    }
  }
}
